/**
 * 
 */
package gui;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import main.Session;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.MessageBox;
import DB.EditFilm;
import DB.EditProgram;
import DB.SearchDB;
import DB.User_managment;
import Utils.Concurrent.LoaderRunner;
import Utils.Concurrent.ThreadTasks.*;
import datatype.User;
import gamePlay.Play;

/**
 * @author Yuval
 * 
 *         the main class that manage all the gui, create all the side classes
 *         that handle the individual sections in tha application prepare the
 *         widgets, and some other stuff
 * 
 */
public class GUI_manager extends GUI {

	private Timer timer = new Timer(display, gameTimer);
	private OpenConnectionsTask openConnectionsTask;
	private ChangePassTask changePassTask;
	// private LoaderGif loginLoader;
	private User_managment user_managment = new User_managment(userManagment,
			userMan_commitBTN, mainManageUsersBTN, userMan_returnBTN,
			userMan_refreshBTN, userMan_loadingCNVS);

	private SearchDB searchDB = new SearchDB(searchENG_searchTXT,
			searchENG_GoBTN, searchENG_tvTBL, searchENG_filmTBL,
			searchENG_actorTBL, searchENG_creatorTBL, searchENG_directorTBL,
			searchENG_programBTN, searchENG_filmBTN, searchENG_actorBTN,
			searchENG_programCeatorBTN, searchENG_filmDirectorBTN, editTV,
			editMovie, searchENG_createFilmBTN, searchENG_createProgramBTN,
			searchENG_createActorBTN, searchENG_createCreatorBTN,
			searchENG_createDirectorBTN, searchENG_addPerson,
			searchENG_returnBTN, searchENG_loadingCNVS);

	private EditProgram editProgram = new EditProgram(editTV_programNameTXT,
			editTV_countryTXT, editTV_actorCharaterNameTXT, editTV_firstDateDT,
			editTV_lastDateDT, editTV_numOfSeasonsSPN, editTV_numOfEpisodeSPN,
			editTV_actorsTBL, editTV_creatorsTBL, editTV_commitBTN,
			editTV_cencelBTN, editTV_setNameBTN, editTV_addActorBTN,
			editTV_addCreatorBTN, editTV_searchActorComp,
			editTV_searchCreatorComp, searchENG, editTV_loadingCNVS);

	private EditFilm editFilm = new EditFilm(editFilm_filmNameTXT,
			editFilm_originCountryTXT, editFilm_prequelTXT, editFilm_sequelTXT,
			editFilm_actorCharaterNameTXT, editFilm_releaseDateDT,
			editFilm_estimatedSPN, editFilm_ActorTBL, editFilm_directorsTBL,
			editFilm_commitBTN, editFilm_cencelBTN, editFilm_addActorBTN,
			editFilm_setNameBTN, editFilm_addDirectorBTN,
			editFilm_searchActorComp, editFilm_searchDirectorComp,
			editFilm_searchFilmComp, searchENG, editFilm_loadingCNVS);

	private Play play = new Play(startGameScreen, nextLevel, loadingQuestion,
			statistics, game, mainScreen, mainStartLevelBTN, mainStartLongBTN,
			start_game_startBTN, nextLevel_nextBTN, loadingQuestion_continue,
			stats_continue, game_question, timer, start_game_infoLBL,
			nextLevel_infoLBL, stats_statsLBL, stats_updateLBL,
			stats_loadingCNVS);

	public void changeScreenTo(Composite c) {
		layout.topControl = c;
		shell.layout();
	}

	public void introLoginBTN_afterDB() {
		User user = Session.user;
		login_loaderCNVS.setVisible(false);
		if (user == null) {
			login_loadingLBL.setText("Wrong username or password");
			// showTextBoxWithOk("login fail", "Wrong username or password",
			// SWT.ICON_WARNING);
		} else {

			// showTextBoxWithOk("cool", "Welcome", SWT.ICON_WORKING);
			introClear();
			changeScreenTo(mainScreen);

			// dont show the admin DB manage buttons
			boolean isToShow = false;

			if (Session.user.getPrivil() == 1)
				isToShow = false;
			else
				isToShow = true;

			mainEditDbBTN.setVisible(isToShow);
			mainSearchBTN.setVisible(isToShow);
			mainManageUsersBTN.setVisible(isToShow);
			mainAdminTitleLBL.setVisible(isToShow);

		}
	}

	public void introClear() {
		login_username_enter.setText("");
		login_password_enter.setText("");
		login_loadingLBL.setText("");

	}

	/**
	 * implement the register button click event connect to the DB, and ask if
	 * the user name exist, if yes return 0, else return the new user id in the
	 * DB
	 * 
	 */
	public void regConinueBTN(LoaderGif lg) {
		regis_loadingLBL.setText("");

		if (regis_password1_enter.getText() != ""
				&& regis_password2_enter.getText() != ""
				&& regis_firstname_enter.getText() != ""
				&& regis_lastname_enter.getText() != ""
				&& regis_username_enter.getText() != "") {

			if (regis_password1_enter.getText().equals(
					regis_password2_enter.getText())) {
				// LoaderRunner loadR = new LoaderRunner(display,
				// regis_loadingLBL, "registrating");
				RegistraionTask registraionTask = new RegistraionTask(display,
						regis_firstname_enter.getText(),
						regis_lastname_enter.getText(),
						regis_username_enter.getText(),
						regis_password1_enter.getText(), lg, regis_loadingLBL);
				// lg.showLoader();
				Session.poolForLogin.pushUrgentTask(registraionTask,
						lg.getLoaderTask());

				/*
				 * int userID = Session_new.DB.createUserInDB(
				 * regis_firstname_enter.getText(),
				 * regis_lastname_enter.getText(),
				 * regis_password1_enter.getText(),
				 * regis_username_enter.getText());
				 */

			} else {
				// showTextBoxWithOk("password mismatch",
				// "The password dosn't match", SWT.ICON_WARNING);
				regis_loadingLBL.setText("The password dosn't match");
			}
		} else {
			// showTextBoxWithOk("warning", "please fill in all the fields",
			// SWT.ICON_WARNING);
			regis_loadingLBL.setText("please fill in all the fields");
		}

	}

	public void afterConnecting() {
		shell.setSize(1024, 768);
		changeScreenTo(Login);

	}

	public void registration_afterDB(int userID) {
		regis_loadingCNVS.setVisible(false);
		if (userID == 0) {
			regis_loadingLBL
					.setText("The user name exits\r please choose somthing else");
			regis_loadingLBL.setVisible(true);
		} else if (userID == -1) {
			regis_loadingLBL
					.setText("error in connection, please call to the hot line");
		} else {
			User user = new User(regis_firstname_enter.getText(),
					regis_lastname_enter.getText(), 0,
					regis_password1_enter.getLineDelimiter(),
					regis_username_enter.getText(), userID);
			Session.user = user;
			changeScreenTo(Login);
			regClear();

		}
	}

	public void regClear() {
		regis_firstname_enter.setText("");
		regis_lastname_enter.setText("");
		regis_username_enter.setText("");
		regis_password1_enter.setText("");
		regis_password2_enter.setText("");
		regis_availabilityLBL.setText("");
		regis_loadingLBL.setText("");
	}

	public void mainLogoutBTN() {
		Session.user = null;
		changeScreenTo(Login);

	}

	public void setEventToGadgets() {
		LoaderGif lgForConnecting = new LoaderGif(loading_loaderCNVS, 4);
		openConnectionsTask = new OpenConnectionsTask(display, lgForConnecting);
		Session.pool.pushUrgentTask(openConnectionsTask,
				lgForConnecting.getLoaderTask());

		loginRegisterBTN.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent arg0) {
				Session.poolForLogin.killAll();
				introClear();
				changeScreenTo(register);
			}
		});

		loginLoginBTN.addMouseListener(new MouseAdapter() {

			LoaderGif lg = new LoaderGif(login_loaderCNVS, 1);

			@SuppressWarnings("unchecked")
			@Override
			public void mouseDown(MouseEvent arg0) {

				login_loadingLBL.setText("");

				if (login_password_enter.getText() == ""
						|| login_username_enter.getText() == "") {
					login_loadingLBL
							.setText("please enter username and password");
				} else {

					// LoaderRunner loaderR = new LoaderRunner(display,
					// login_loadingLBL, "loading user");
					LoginTask loginTask = new LoginTask(display,
							login_username_enter.getText(),
							login_password_enter.getText(), lg);
					lg.showLoader();
					Session.poolForLogin.pushUrgentTask(loginTask,
							lg.getLoaderTask());
				}

			}
		});

		regisbackBTN.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent arg0) {
				regClear();
				changeScreenTo(Login);
				Session.poolForLogin.killAll();
				regis_loadingCNVS.setVisible(false);
			}
		});

		regisConinueBTN.addMouseListener(new MouseAdapter() {

			LoaderGif lg = new LoaderGif(regis_loadingCNVS, 2);

			@Override
			public void mouseDown(MouseEvent arg0) {
				regConinueBTN(lg);
			}
		});

		regis_username_enter.addModifyListener(new ModifyListener() {

			AvailabilityTask avaTask = null;
			LoaderRunner loaderR = null;

			@Override
			public void modifyText(ModifyEvent arg0) {

				if (!regis_username_enter.getText().equals("")) {
					loaderR = new LoaderRunner(display, regis_availabilityLBL,
							"checking availability");
					String str = regis_username_enter.getText();

					avaTask = new AvailabilityTask(display, str, loaderR,
							regis_availabilityLBL);

					// push task to the front and shutdown others
					Session.poolForLogin.pushUrgentTask(avaTask, loaderR);
				}

			}
		});

		editDB_clearBTN.addMouseListener(new MouseAdapter() {
			LongDBoperationTask longDBoperationTask = null;
			LoaderGif lg = null;

			@Override
			public void mouseDown(MouseEvent arg0) {

				if (longDBoperationTask != null)
					Session.pool.killAll(longDBoperationTask);

				if (lg == null)
					lg = new LoaderGif(editDB_longLoadingCNVS, 4);

				editDB_clearBTN.setEnabled(false);
				editDB_enterBTN.setEnabled(false);
				editDB_updateBTN.setEnabled(false);
				editDB_returnBTN.setEnabled(false);
				editDB_longLoadingCNVS.setVisible(true);

				longDBoperationTask = new LongDBoperationTask(display, lg, 1);
				Session.pool.pushUrgentTask(longDBoperationTask,
						lg.getLoaderTask());
			}
		});

		editDB_enterBTN.addMouseListener(new MouseAdapter() {
			LongDBoperationTask longDBoperationTask = null;
			LoaderGif lg = null;

			@Override
			public void mouseDown(MouseEvent arg0) {

				if (longDBoperationTask != null)
					Session.pool.killAll(longDBoperationTask);

				if (lg == null)
					lg = new LoaderGif(editDB_longLoadingCNVS, 4);

				editDB_clearBTN.setEnabled(false);
				editDB_enterBTN.setEnabled(false);
				editDB_updateBTN.setEnabled(false);
				editDB_returnBTN.setEnabled(false);
				editDB_longLoadingCNVS.setVisible(true);
				editDB_loadingLBL.setVisible(true);

				longDBoperationTask = new LongDBoperationTask(display, lg, 3);
				Session.pool.pushUrgentTask(longDBoperationTask,
						lg.getLoaderTask());
			}
		});

		editDB_updateBTN.addMouseListener(new MouseAdapter() {
			LongDBoperationTask longDBoperationTask = null;
			LoaderGif lg = null;

			@Override
			public void mouseDown(MouseEvent arg0) {

				if (longDBoperationTask != null)
					Session.pool.killAll(longDBoperationTask);

				if (lg == null)
					lg = new LoaderGif(editDB_longLoadingCNVS, 4);

				editDB_clearBTN.setEnabled(false);
				editDB_enterBTN.setEnabled(false);
				editDB_updateBTN.setEnabled(false);
				editDB_returnBTN.setEnabled(false);
				editDB_longLoadingCNVS.setVisible(true);
				editDB_loadingLBL.setVisible(true);

				longDBoperationTask = new LongDBoperationTask(display, lg, 2);
				Session.pool.pushUrgentTask(longDBoperationTask,
						lg.getLoaderTask());
			}
		});

		mainEditDbBTN.addMouseListener(new MouseAdapter() {
			GetDB_StatsTask getDB_StatsTask = null;
			LoaderGif lg = null;

			@Override
			public void mouseDown(MouseEvent arg0) {

				editDB_clearBTN.setEnabled(false);
				editDB_enterBTN.setEnabled(false);
				editDB_updateBTN.setEnabled(false);
				editDB_returnBTN.setEnabled(false);

				if (lg == null)
					lg = new LoaderGif(editDB_loadingCNVS, 4);

				if (getDB_StatsTask != null)
					Session.pool.killAll(getDB_StatsTask);

				getDB_StatsTask = new GetDB_StatsTask(display, lg);
				Session.pool.pushUrgentTask(getDB_StatsTask, lg.getLoaderTask());
				changeScreenTo(editDB);
			}
		});

		editDB_returnBTN.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent arg0) {
				changeScreenTo(mainScreen);

			}
		});

		mainSearchBTN.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				changeScreenTo(searchENG);
			}

		});

		mainProfileBTN.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				prepareProfile();
				changeScreenTo(profile);
			}
		});

		profile_returnBTN.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				changeScreenTo(mainScreen);
			}

		});

		profile_changePassBTN.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				profile_returnBTN.setEnabled(false);
				setVisibilty(true);
				profile_loadingCNVS.setVisible(false);

			}

		});

		profile_cancelBTN.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				if (changePassTask != null)
					Session.poolForLogin.killAll(changePassTask);
				afterChangePass();
			}

		});

		profile_commitBTN.addMouseListener(new MouseAdapter() {
			LoaderGif lg = new LoaderGif(profile_loadingCNVS, 1);

			@Override
			public void mouseDown(MouseEvent arg0) {
				if (profile_oldPassTXT.getText().equals(
						Session.user.getPassword())
						&& profile_newPassTXT.getText().equals(
								profile_RenewPassTXT.getText())
						&& !profile_RenewPassTXT.getText().equals("")) {

					if (changePassTask != null)
						Session.poolForLogin.killAll(changePassTask);

					changePassTask = new ChangePassTask(display, Session.user
							.getId(), profile_RenewPassTXT.getText(), lg);
					lg.showLoader();
					Session.poolForLogin.pushUrgentTask(changePassTask,
							lg.getLoaderTask());

				} else {
					showTextBoxWithOk("wrong password",
							"The password dosnt match", SWT.ERROR);
				}
			}
		});

		mainLogoutBTN.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				Session.user = null;
				changeScreenTo(Login);
			}

		});

		prepareCountryAutoComplete();
		setVisibilty(false);
		shell.layout();

	}

	public void afterChangePass() {
		setVisibilty(false);
		profile_oldPassTXT.setText("");
		profile_newPassTXT.setText("");
		profile_RenewPassTXT.setText("");
		profile_returnBTN.setEnabled(true);
		profile_loadingCNVS.setVisible(false);
	}

	private void prepareCountryAutoComplete() {

		editTV.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				editTV_countryListcomLST.setVisible(false);
			}

		});
		/*
		 * editTV_countryTXT.addModifyListener(new ModifyListener() {
		 * 
		 * @Override public void modifyText(ModifyEvent arg0) {
		 * 
		 * editTV_countryListcomLST.removeAll();
		 * 
		 * if (editTV_countryTXT.getText().length() > 0) {
		 * 
		 * List<String> res = getCountry(editTV_countryTXT.getText()); for
		 * (String s : res) editTV_countryListcomLST.add(s);
		 * editTV_countryListcomLST.setVisible(true); } } });
		 */
		editTV_countryListcomLST.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent arg0) {
				int selected = editTV_countryListcomLST.getSelectionIndex();
				if (editTV_countryListcomLST.getItemCount() > selected
						&& selected >= 0) {
					editTV_countryTXT.setText(editTV_countryListcomLST
							.getItem(selected));
				}
				editTV_countryListcomLST.setVisible(false);
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
			}
		});

		editTV_countryListcomLST.addFocusListener(new FocusAdapter() {

			@Override
			public void focusLost(FocusEvent arg0) {
				editTV_countryListcomLST.setVisible(false);
			}

		});
		/*
		 * editFilm_originCountryTXT.addModifyListener(new ModifyListener() {
		 * 
		 * @Override public void modifyText(ModifyEvent arg0) {
		 * 
		 * editFilm_countryListcomLST.removeAll(); if
		 * (editFilm_originCountryTXT.getText().length() > 0) {
		 * 
		 * List<String> res = getCountry(editFilm_originCountryTXT .getText());
		 * for (String s : res) editFilm_countryListcomLST.add(s);
		 * editFilm_countryListcomLST.setVisible(true); } } });
		 */
		editMovie.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				editFilm_countryListcomLST.setVisible(false);
			}

		});

		editFilm_countryListcomLST
				.addSelectionListener(new SelectionListener() {

					@Override
					public void widgetSelected(SelectionEvent arg0) {
						int selected = editFilm_countryListcomLST
								.getSelectionIndex();
						if (editFilm_countryListcomLST.getItemCount() > selected
								&& selected >= 0) {
							editFilm_originCountryTXT
									.setText(editFilm_countryListcomLST
											.getItem(selected));
						}
						editFilm_countryListcomLST.setVisible(false);

					}

					@Override
					public void widgetDefaultSelected(SelectionEvent arg0) {
					}
				});

		editFilm_countryListcomLST.addFocusListener(new FocusAdapter() {

			@Override
			public void focusLost(FocusEvent arg0) {
				editTV_countryListcomLST.setVisible(false);
			}
		});

	}

	public void afterDBmanage() {
		editDB_clearBTN.setEnabled(true);
		editDB_enterBTN.setEnabled(true);
		editDB_updateBTN.setEnabled(true);
		editDB_returnBTN.setEnabled(true);
		editDB_loadingLBL.setVisible(false);
		editDB_longLoadingCNVS.setVisible(false);
	}

	public void editDB_afterDB(String info) {
		editDB_clearBTN.setEnabled(true);
		editDB_enterBTN.setEnabled(true);
		editDB_updateBTN.setEnabled(true);
		editDB_returnBTN.setEnabled(true);
		editDB_infoLBL.setText(info);

	}

	private void prepareProfile() {

		User u = Session.user;
		String str = "First name: " + u.getFirst_name() + "\r" + "Last name: "
				+ u.getLast_name() + "\r" + "Username: " + u.getUserName()
				+ "\r\r" + "Best Level mod score: " + u.getBestLevel() + "\r"
				+ "Best Long mod score: " + u.getBestLong();

		profile_infoLBL.setText(str);
	}

	private List<String> getCountry(String firstLetters) {

		List<String> res = new ArrayList<String>();

		for (Locale l : Locale.getAvailableLocales()) {
			if (l.getDisplayCountry().toLowerCase()
					.startsWith(firstLetters.toLowerCase()))
				res.add(l.getDisplayCountry().toLowerCase());
		}
		if (res.isEmpty())
			res.add("no results");
		return res;
	}

	public void showTextBoxWithOk(String title, String messege, int icon) {
		MessageBox messageBox = new MessageBox(shell, icon | SWT.OK);

		messageBox.setText(title);
		messageBox.setMessage(messege);
		messageBox.open();

	}

	public void showErrorMsgBox(String errMsg) {

		MessageBox messageBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);

		messageBox.setText(errMsg);
		messageBox.setMessage(errMsg);
		messageBox.open();

		shell.dispose();

	}

	private void setVisibilty(boolean visi) {

		for (Control c : profile_changePassCOMP.getChildren()) {
			c.setVisible(visi);
		}
		profile_changePassCOMP.setVisible(visi);

	}

	public User_managment getUser_managment() {
		return user_managment;
	}

	public void setUser_managment(User_managment user_managment) {
		this.user_managment = user_managment;
	}

	public SearchDB getSearchDB() {
		return searchDB;
	}

	public void setSearchDB(SearchDB searchDB) {
		this.searchDB = searchDB;
	}

	public EditProgram getEditProgram() {
		return editProgram;
	}

	public void setEditProgram(EditProgram editProgram) {
		this.editProgram = editProgram;
	}

	public EditFilm getEditFilm() {
		return editFilm;
	}

	public void setEditFilm(EditFilm editFilm) {
		this.editFilm = editFilm;
	}

	public Play getPlay() {
		return play;
	}

	public void setPlay(Play play) {
		this.play = play;
	}

}
